            
            
class Person {
    constructor(name: string, age: number) {}
  }
  class Animal {
    constructor(name: string, age: number) {}
  }
  interface IClass<T> {
    new (name: string, age: number): T;
  }
  function createInstance<T>(target: IClass<T>, name: string, age: number) {
    return new target(name, age);
  }
  //ts没有执行，所以不能确认name的类型，需要as string
  function createInstance1<T, K>(target: IClass<T>, name: K, age: number) {
    return new target(name as string, age);
  }
  const animal = createInstance(Animal, "cat", 2);
  
  //--------------------根据提供的数据生成对应长度的数组---------------
  //函数声明
  function createArray<U>(len: number, val: U) {
    const result = [] as U[];
    for (let index = 0; index < len; index++) {
      result.push(val);
      return result;
    }
  }
  //函数表达式
  // const  createArray=<U>(len:number,val:U)=>{
  //     const result=[] as U[]
  //     for (let index = 0; index < len; index++) {
  //          result.push(val)
  //          return result;
  //     }
  // }
  const dd = createArray(3, "ee");
  
  //--------------------2个泛型，函数位置交换--------------------
  
  const reverseArr = <K, T>(arr: [K, T]): [T, K] => {
    return [arr[1], arr[0]];
  };
  // type IReverseArr=<K,T>(arr:[K,T])=>[T,K] //这种写法，后面可以复用
  interface IReverseArr {
    <K, T>(arr: [K, T]): [T, K];
  }
  const reverseArr1: IReverseArr = (arr) => {
    return [arr[1], arr[0]];
  };
  const ss = reverseArr(["ee", 5]);
  const ss1 = reverseArr1(["ee", 5]);
  
  //--------------------泛型foreach--------------------
  //Icall<T>=(item:T,i:number)=>void：写在等号前面表示使用类型的时候传参，IForeEach=<T>(arr:T[],vall:Icall<T>)=>void：写在函数前面表示调用的时候传递参数
  type Icall<T>=(item:T,i:number)=>void
  type IForeEach=<T>(arr:T[],vall:Icall<T>)=>void;
  const forEach:IForeEach = (arr, call) => {
    for (let index = 0; index < arr.length; index++) {
      call(arr[index], index);
    }
  };
  const forEach1 = <T>(arr:T[], call:(item:T,i:number)=>void) => {
      for (let index = 0; index < arr.length; index++) {
        call(arr[index], index);
      }
    };
   forEach([1,'3'],(item,i)=>{
  
  })
  
  
  //--------------------泛型默认--------------------
  //泛型是有默认的，在使用一些联合类型的时候，会使用
  type Union<T=boolean>=T| string | number; //T 的默认类型是boolean ,可以传可以不传，不传默认是boolean
  const  union:Union<{}>={}
  
  //--------------------泛型约束--------------------
  //要求传递必须伏符合要求，A extends B;,A是B的子类或者同类
  //什么叫子类，什么叫父类型，对于对象而言，子类是比父类多的或者一样多
  
  //传递必须是string.number
  const handel1=<T extends string | number>(val:T):T=>{
      return val
  }
  //传递必须是对象和对象的key
   const handel2=<T>(obj:T,key:keyof T)=>{
      return obj[key]
   }
   //传递必须是对象和对象的key
   const handel21=<T,K extends keyof T>(obj:T,key:K)=>{
      return obj[key]
   }
   //传递必须包含length属性
   interface IWidthLength {
      length:number
   }
   function handle2<T extends IWidthLength>(val:T){
      return val
   }
   handle2({s:1,length:2})
  
  //--------------------通过泛型来占坑位--------------------
  interface ILoginDate{
          token:string,
          roles:number[]
  }
  interface IReponseData{
      page:number,
      total:number,
      list:number[]
  }
  interface ITologin<ILoginDate>{
      code:number,
      message?:string,
      data:ILoginDate
  }
  const toLogin=():ITologin<ILoginDate>=>{ //通过ILoginDate来传入不同的data类型
      return {
          code:200,
          message:'',
          data:{
              token:'354654321' ,
              roles:[1,3,4]
          }
      }
  }
  
  const toResponse=():ITologin<IReponseData>=>{
      return {
          code:200,
          message:'',
          data:{
             page:1,
             total:23,
             list:[3]
          }
      }
  }
  
  //--------------------泛型-获取最大值--------------------
  class MyArr<T>{
      private arr:T[]=[]
      set(num:T){
      this.arr.push(num)
      }
      getMax(){
          let arr=this.arr;
          let max=arr[0]
          for (let index = 0; index < arr.length; index++) {
              const element = arr[index];
              element>max ? max=element : void 0;
              
          }
          return max;
      }
  }
  
  const myArr=new MyArr<number>()
  myArr.set(1)
  myArr.set(3)
  myArr.set(2)
  const getMax=myArr.getMax()